package com.lzj.gen.jetbrains;

import com.alibaba.fastjson.JSONObject;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;

/**
 * 生成licenseId
 */
public class CodeUtil {

    private static final Base64.Encoder BASE64_ENCODER = Base64.getEncoder();

    public static String genActiveCode(String certFile, String keyFile, String licenseJsonStr)
            throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException,
            IOException, SignatureException, CertificateException {

        byte[] certBytes = PemUtil.readPem(certFile);
        String certFullStr = PemUtil.readPemFullStr(certFile);
        String certStr = BASE64_ENCODER.encodeToString(certBytes);
        byte[] privateKeyBytes = PemUtil.readPem(keyFile);

        //PKCS#8
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
        KeyFactory keyFactory= KeyFactory.getInstance("RSA");
        PrivateKey priKey= keyFactory.generatePrivate(pkcs8KeySpec);

        JSONObject licenseObj = JSONObject.parseObject(licenseJsonStr);
        String licenseId = licenseObj.getString("licenseId");
        byte[] licenseBytes = licenseJsonStr.getBytes("utf-8");

        Signature privateSignature = Signature.getInstance("SHA1withRSA");
        privateSignature.initSign(priKey);
        privateSignature.update(licenseBytes);
        byte[] signature = privateSignature.sign();

        CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
        X509Certificate x509Certificate = (X509Certificate) certFactory.generateCertificate(
                new ByteArrayInputStream(certFullStr.getBytes()));
        Signature publicSignature = Signature.getInstance("SHA1withRSA");
        publicSignature.initVerify(x509Certificate.getPublicKey());
        publicSignature.update(licenseBytes);
        if (!publicSignature.verify(signature)) {
            throw new RuntimeException("signature verify error");
        }
        return licenseId + "-" + BASE64_ENCODER.encodeToString(licenseBytes) +
                "-" + BASE64_ENCODER.encodeToString(signature) + "-" + certStr;
    }

    public static void main(String[] args) {
        String a = "eyJsaWNlbnNlSWQiOiI1UThJNFVTRjJEIiwibGljZW5zZWVOYW1lIjoi5LitIOaxnyIsImxpY2Vuc2VlVHlwZSI6IlBFUlNPTkFMIiwiYXNzaWduZWVOYW1lIjoiIiwiYXNzaWduZWVFbWFpbCI6IiIsImxpY2Vuc2VSZXN0cmljdGlvbiI6IiIsImNoZWNrQ29uY3VycmVudFVzZSI6ZmFsc2UsInByb2R1Y3RzIjpbeyJjb2RlIjoiR08iLCJmYWxsYmFja0RhdGUiOiIyMDI0LTA3LTAyIiwicGFpZFVwVG8iOiIyMDI1LTA3LTAxIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJSUzAiLCJmYWxsYmFja0RhdGUiOiIyMDI0LTA3LTAyIiwicGFpZFVwVG8iOiIyMDI1LTA3LTAxIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJETSIsImZhbGxiYWNrRGF0ZSI6IjIwMjQtMDctMDIiLCJwYWlkVXBUbyI6IjIwMjUtMDctMDEiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IkNMIiwiZmFsbGJhY2tEYXRlIjoiMjAyNC0wNy0wMiIsInBhaWRVcFRvIjoiMjAyNS0wNy0wMSIsImV4dGVuZGVkIjpmYWxzZX0seyJjb2RlIjoiQUMiLCJmYWxsYmFja0RhdGUiOiIyMDIzLTEyLTMxIiwicGFpZFVwVG8iOiIyMDI1LTA3LTAxIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJSU1UiLCJmYWxsYmFja0RhdGUiOiIyMDI0LTA3LTAyIiwicGFpZFVwVG8iOiIyMDI1LTA3LTAxIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJSU0MiLCJmYWxsYmFja0RhdGUiOiIyMDI0LTA3LTAyIiwicGFpZFVwVG8iOiIyMDI1LTA3LTAxIiwiZXh0ZW5kZWQiOnRydWV9LHsiY29kZSI6IlBDIiwiZmFsbGJhY2tEYXRlIjoiMjAyNC0wNy0wMiIsInBhaWRVcFRvIjoiMjAyNS0wNy0wMSIsImV4dGVuZGVkIjpmYWxzZX0seyJjb2RlIjoiRFMiLCJmYWxsYmFja0RhdGUiOiIyMDI0LTA3LTAyIiwicGFpZFVwVG8iOiIyMDI1LTA3LTAxIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJSRCIsImZhbGxiYWNrRGF0ZSI6IjIwMjQtMDctMDIiLCJwYWlkVXBUbyI6IjIwMjUtMDctMDEiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IlFBIiwiZmFsbGJhY2tEYXRlIjoiMjAyNC0wNy0wMiIsInBhaWRVcFRvIjoiMjAyNS0wNy0wMSIsImV4dGVuZGVkIjpmYWxzZX0seyJjb2RlIjoiUkMiLCJmYWxsYmFja0RhdGUiOiIyMDI0LTA3LTAyIiwicGFpZFVwVG8iOiIyMDI1LTA3LTAxIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJSU0YiLCJmYWxsYmFja0RhdGUiOiIyMDI0LTA3LTAyIiwicGFpZFVwVG8iOiIyMDI1LTA3LTAxIiwiZXh0ZW5kZWQiOnRydWV9LHsiY29kZSI6IlJNIiwiZmFsbGJhY2tEYXRlIjoiMjAyNC0wNy0wMiIsInBhaWRVcFRvIjoiMjAyNS0wNy0wMSIsImV4dGVuZGVkIjpmYWxzZX0seyJjb2RlIjoiSUkiLCJmYWxsYmFja0RhdGUiOiIyMDI0LTA3LTAyIiwicGFpZFVwVG8iOiIyMDI1LTA3LTAxIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJEUE4iLCJmYWxsYmFja0RhdGUiOiIyMDI0LTA3LTAyIiwicGFpZFVwVG8iOiIyMDI1LTA3LTAxIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJEQiIsImZhbGxiYWNrRGF0ZSI6IjIwMjQtMDctMDIiLCJwYWlkVXBUbyI6IjIwMjUtMDctMDEiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IkRDIiwiZmFsbGJhY2tEYXRlIjoiMjAyNC0wNy0wMiIsInBhaWRVcFRvIjoiMjAyNS0wNy0wMSIsImV4dGVuZGVkIjpmYWxzZX0seyJjb2RlIjoiUFMiLCJmYWxsYmFja0RhdGUiOiIyMDI0LTA3LTAyIiwicGFpZFVwVG8iOiIyMDI1LTA3LTAxIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJSUiIsImZhbGxiYWNrRGF0ZSI6IjIwMjQtMDctMDIiLCJwYWlkVXBUbyI6IjIwMjUtMDctMDEiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IlJTViIsImZhbGxiYWNrRGF0ZSI6IjIwMjQtMDctMDIiLCJwYWlkVXBUbyI6IjIwMjUtMDctMDEiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiV1MiLCJmYWxsYmFja0RhdGUiOiIyMDI0LTA3LTAyIiwicGFpZFVwVG8iOiIyMDI1LTA3LTAxIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJQU0kiLCJmYWxsYmFja0RhdGUiOiIyMDI0LTA3LTAyIiwicGFpZFVwVG8iOiIyMDI1LTA3LTAxIiwiZXh0ZW5kZWQiOnRydWV9LHsiY29kZSI6IlBDV01QIiwicGFpZFVwVG8iOiIyMDI1LTA3LTAxIiwiZXh0ZW5kZWQiOnRydWV9LHsiY29kZSI6IkFJTCIsInBhaWRVcFRvIjoiMjAyNS0wNy0wMSIsImV4dGVuZGVkIjpmYWxzZX0seyJjb2RlIjoiUlMiLCJmYWxsYmFja0RhdGUiOiIyMDI0LTA3LTAyIiwicGFpZFVwVG8iOiIyMDI1LTA3LTAxIiwiZXh0ZW5kZWQiOnRydWV9LHsiY29kZSI6IkRQIiwiZmFsbGJhY2tEYXRlIjoiMjAyNC0wNy0wMiIsInBhaWRVcFRvIjoiMjAyNS0wNy0wMSIsImV4dGVuZGVkIjp0cnVlfSx7ImNvZGUiOiJQREIiLCJmYWxsYmFja0RhdGUiOiIyMDI0LTA3LTAyIiwicGFpZFVwVG8iOiIyMDI1LTA3LTAxIiwiZXh0ZW5kZWQiOnRydWV9LHsiY29kZSI6IlBSUiIsImZhbGxiYWNrRGF0ZSI6IjIwMjQtMDctMDIiLCJwYWlkVXBUbyI6IjIwMjUtMDctMDEiLCJleHRlbmRlZCI6dHJ1ZX1dLCJtZXRhZGF0YSI6IjAyMjAyNTAzMDVQUEFBMDEwMDA3QSIsImhhc2giOiIzNTQ4NTIwMC8wOjEyNDk1NTA0MDIiLCJncmFjZVBlcmlvZERheXMiOjcsImF1dG9Qcm9sb25nYXRlZCI6ZmFsc2UsImlzQXV0b1Byb2xvbmdhdGVkIjpmYWxzZSwidHJpYWwiOmZhbHNlLCJhaUFsbG93ZWQiOnRydWV9";
        String s = new String(Base64.getDecoder().decode(a), StandardCharsets.UTF_8);
        System.out.println(s);
        // {"licenseId":"5Q8I4USF2D","licenseeName":"中 江","licenseeType":"PERSONAL","assigneeName":"","assigneeEmail":"","licenseRestriction":"","checkConcurrentUse":false,"products":[{"code":"GO","fallbackDate":"2024-07-02","paidUpTo":"2025-07-01","extended":false},{"code":"RS0","fallbackDate":"2024-07-02","paidUpTo":"2025-07-01","extended":false},{"code":"DM","fallbackDate":"2024-07-02","paidUpTo":"2025-07-01","extended":false},{"code":"CL","fallbackDate":"2024-07-02","paidUpTo":"2025-07-01","extended":false},{"code":"AC","fallbackDate":"2023-12-31","paidUpTo":"2025-07-01","extended":false},{"code":"RSU","fallbackDate":"2024-07-02","paidUpTo":"2025-07-01","extended":false},{"code":"RSC","fallbackDate":"2024-07-02","paidUpTo":"2025-07-01","extended":true},{"code":"PC","fallbackDate":"2024-07-02","paidUpTo":"2025-07-01","extended":false},{"code":"DS","fallbackDate":"2024-07-02","paidUpTo":"2025-07-01","extended":false},{"code":"RD","fallbackDate":"2024-07-02","paidUpTo":"2025-07-01","extended":false},{"code":"QA","fallbackDate":"2024-07-02","paidUpTo":"2025-07-01","extended":false},{"code":"RC","fallbackDate":"2024-07-02","paidUpTo":"2025-07-01","extended":false},{"code":"RSF","fallbackDate":"2024-07-02","paidUpTo":"2025-07-01","extended":true},{"code":"RM","fallbackDate":"2024-07-02","paidUpTo":"2025-07-01","extended":false},{"code":"II","fallbackDate":"2024-07-02","paidUpTo":"2025-07-01","extended":false},{"code":"DPN","fallbackDate":"2024-07-02","paidUpTo":"2025-07-01","extended":false},{"code":"DB","fallbackDate":"2024-07-02","paidUpTo":"2025-07-01","extended":false},{"code":"DC","fallbackDate":"2024-07-02","paidUpTo":"2025-07-01","extended":false},{"code":"PS","fallbackDate":"2024-07-02","paidUpTo":"2025-07-01","extended":false},{"code":"RR","fallbackDate":"2024-07-02","paidUpTo":"2025-07-01","extended":false},{"code":"RSV","fallbackDate":"2024-07-02","paidUpTo":"2025-07-01","extended":true},{"code":"WS","fallbackDate":"2024-07-02","paidUpTo":"2025-07-01","extended":false},{"code":"PSI","fallbackDate":"2024-07-02","paidUpTo":"2025-07-01","extended":true},{"code":"PCWMP","paidUpTo":"2025-07-01","extended":true},{"code":"AIL","paidUpTo":"2025-07-01","extended":false},{"code":"RS","fallbackDate":"2024-07-02","paidUpTo":"2025-07-01","extended":true},{"code":"DP","fallbackDate":"2024-07-02","paidUpTo":"2025-07-01","extended":true},{"code":"PDB","fallbackDate":"2024-07-02","paidUpTo":"2025-07-01","extended":true},{"code":"PRR","fallbackDate":"2024-07-02","paidUpTo":"2025-07-01","extended":true}],"metadata":"0220250305PPAA010007A","hash":"35485200/0:1249550402","gracePeriodDays":7,"autoProlongated":false,"isAutoProlongated":false,"trial":false,"aiAllowed":true}
    }

}
